﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using haptic.src.engine.design;
using haptic.src.engine.render;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;

namespace haptic.src.engine.animation
{
    [Serializable]
    public abstract class StateEffect
    {
        #region Constructors
        public StateEffect(){ }
        #endregion

        #region Init
        public abstract void Initialize();
        #endregion

        #region Load
        public virtual void Load(ContentManager oContent)
        {

        }
        #endregion

        #region Update
        public virtual void Update(float fCurrentTimeRatio, AutomateInstance.Context oContext)
        {
        }
        #endregion

        #region Draw
        public virtual void Draw(Renderer oRenderer, AutomateInstance.Context oDrawContext)
        {

        }
        #endregion

        #region Attributes
        #endregion
    }

    [Serializable]
    public class StateEffectSprite : StateEffect
    {
        #region Constructors
        public StateEffectSprite(){}
        public StateEffectSprite(Sprite oSprite)
        {
            Debug.Assert(oSprite != null);
            m_oSprite = oSprite;
            Initialize();
        }
        #endregion

        #region Init
        public override void Initialize()
        {
            m_oRect = new Rectangle(0, 0, (int)m_oSprite.m_uiFrameWidth, (int)m_oSprite.m_uiFrameHeight);
            m_eSpriteEffects = SpriteEffects.None;
            if (m_bFlipHorizontally)
                m_eSpriteEffects |= SpriteEffects.FlipHorizontally;
            if (m_bFlipVertically)
                m_eSpriteEffects |= SpriteEffects.FlipVertically;
        }
        #endregion

        #region Load
        public override void Load(ContentManager oContent)
        {
            if (m_oSprite != null)
            {
                m_oSprite.Load(oContent);
                Initialize();
            }
        }
        #endregion

        #region Update
        public override void Update(float fCurrentTimeRatio, AutomateInstance.Context oContext)
        {
            if (m_oSprite != null)
            {
                int iFrameIndex = (int)(fCurrentTimeRatio * (float)(m_oSprite.m_uiFrameCount));
                while (iFrameIndex >= m_oSprite.m_uiFrameCount)
                    iFrameIndex -= (int)(m_oSprite.m_uiFrameCount);
                Debug.Assert(iFrameIndex >= 0);
                Debug.Assert(iFrameIndex < m_oSprite.m_uiFrameCount);
                m_oRect.X = iFrameIndex * (int)m_oSprite.m_uiFrameWidth;
            }
        }
        #endregion

        #region Draw
        public override void Draw(Renderer oRenderer, AutomateInstance.Context oDrawContext)
        {
            if (m_oSprite != null)
            {
                SpriteEffects eSpriteEffects = m_eSpriteEffects;
                if (m_bAutoFlip && oDrawContext.m_vFacingDirection.X < 0.0f)
                {
                    if ((eSpriteEffects & SpriteEffects.FlipHorizontally) != 0)
                        eSpriteEffects &= ~SpriteEffects.FlipHorizontally;
                    else
                        eSpriteEffects |= SpriteEffects.FlipHorizontally;
                }
                Vector2 vOrigin = oDrawContext.m_vPosition;
                vOrigin.X -= (float)(m_oSprite.m_uiFrameWidth / 2);
                vOrigin.Y -= (float)(m_oSprite.m_uiFrameHeight / 2);
                oRenderer.DrawSprite(m_oSprite, vOrigin, m_oRect, eSpriteEffects);
            }
        }
        #endregion

        #region Attributes
        [XmlElement("sprite")]
        public Sprite m_oSprite;
        private Rectangle m_oRect;
        [XmlAttribute("flip-x")]
        public bool m_bFlipHorizontally = false;
        [XmlAttribute("flip-y")]
        public bool m_bFlipVertically = false;
        [XmlAttribute("auto-flip")]
        public bool m_bAutoFlip = false;
        private SpriteEffects m_eSpriteEffects = SpriteEffects.None;
        #endregion
    }
}
